﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace Dsl.Ped.Common
{
    /// <summary>
    /// Base class for all ViewModel classes in the application. Provides support for 
    /// property changes notification.
    /// </summary>
    public abstract class ViewModelBase : GalaSoft.MvvmLight.ViewModelBase
    {
        private string[] propertyNames;

        /// <summary>
        /// Raises the PropertyChanged event.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expr"></param>
        protected void RaisePropertyChanged<T>(Expression<Func<T>> expr)
        {
            var memberExpr = expr.Body as MemberExpression;

            if (memberExpr == null || memberExpr.Member.MemberType != MemberTypes.Property)
            {
                string message = string.Format(
                    "The given expression '{0}' does not represent a property of {1}.",
                    expr.ToString(),
                    this.GetType().ToString());
                throw new ArgumentException(message);
            }

            string propertyName = memberExpr.Member.Name;

            RaisePropertyChanged(propertyName);
        }

        /// <summary>
        /// Raises the PropertyChanged event for all properties.
        /// </summary>
        protected void RaiseAllPropertyChanged()
        {
            if (propertyNames == null)
                propertyNames = this.GetType().GetProperties().Select(x => x.Name).ToArray();

            foreach (var propertyName in propertyNames)
            {
                RaisePropertyChanged(propertyName);
            }
        }
    }
}
